package com.glsc.ngateway.platform.service;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.glsc.ngateway.common.api.common.enums.Constant;
import com.glsc.ngateway.common.api.common.enums.DictConstant;
import com.glsc.ngateway.common.api.common.enums.PlatformConstant;
import com.glsc.ngateway.common.api.flowable.resp.FlowableResponse;
import com.glsc.ngateway.common.api.ldap.dto.*;
import com.glsc.ngateway.common.api.ldap.feign.IFeignLdapService;
import com.glsc.ngateway.common.api.ldap.resp.AppEhrResponse;
import com.glsc.ngateway.common.api.ldap.resp.LdapResponse;
import com.glsc.ngateway.common.api.oaflow.dto.oa.OaLinkDto;
import com.glsc.ngateway.common.api.platform.dto.user.PlatformUserDto;
import com.glsc.ngateway.common.api.platform.dto.user.UserLeadersDto;
import com.glsc.ngateway.common.base.converter.platform.PlatformUserConverter;
import com.glsc.ngateway.common.base.domain.mysql.gateway.ldap.LdapEhrEmp;
import com.glsc.ngateway.common.base.domain.mysql.gateway.other.SystemConfig;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.Role;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.Url;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.User;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.UserMenuInfo;
import com.glsc.ngateway.common.base.domain.sqlserver.glsec.TAmEhrDeptinfoEntity;
import com.glsc.ngateway.common.base.enums.UserTypeEnum;
import com.glsc.ngateway.common.base.enums.itflow.FlowConfigValueTypeEnum;
import com.glsc.ngateway.common.base.exception.PlatformException;
import com.glsc.ngateway.common.base.repo.mysql.gateway.platform.MysqlUserMenuInfoRepository;
import com.glsc.ngateway.common.base.repo.mysql.gateway.platform.MysqlUserRepository;
import com.glsc.ngateway.common.base.repo.mysql.gateway.platform.RoleRepo;
import com.glsc.ngateway.common.base.repo.mysql.gateway.platform.UrlRepo;
import com.glsc.ngateway.platform.aspect.UserCache;
import com.google.common.collect.ImmutableList;
import lombok.SneakyThrows;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.util.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Nullable;
import javax.annotation.Resource;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.*;
import java.util.stream.Collectors;

import static com.glsc.ngateway.common.api.common.enums.DictConstant.ROLE_OPEARATOR;

/**
 * 功能描述: <br>
 *
 * @author gaojc
 * @date 2020/9/3 10:42
 */
@Service
public class UserService {
    Logger logger = LoggerFactory.getLogger(UserService.class);

    @Value("${default.password}")
    private String defaultPassword;

    private MysqlUserRepository userRepo;
    private UrlRepo urlRepo;
    @Autowired
    private RoleRepo roleRepo;

    @Resource
    private UserCache userCache;

    @Resource
    private IFeignLdapService feignLdapService;

    @Autowired
    private MysqlUserMenuInfoRepository mysqlUserMenuInfoRepository;//常用菜单用

    @Resource
    private IFeignLdapService iFeignLdapService;

    @Resource
    private SystemConfigService systemConfigService;

    @Autowired
    public void setUserRepo(MysqlUserRepository userRepo) {
        this.userRepo = userRepo;
    }

    @Autowired
    public void setUrlRepo(UrlRepo urlRepo) {
        this.urlRepo = urlRepo;
    }

    @Transactional
    public User add(User user) {
        if (user.getId() != null) {
            throw PlatformException.error("新增用户不要输入id");
        }
        if (Optional.ofNullable(findByUsernameNotSave(user.getUsername())).isPresent()) {
            throw PlatformException.error("账号重复", true, false);
        }
        return userRepo.save(user);
    }

    @Transactional
    public User update(User user) {
        if (user.getId() == null) {
            throw PlatformException.error("用户id不能为空");
        }
        User existUser = userRepo.queryByIdLock(user.getId());
        if (existUser == null) {
            throw PlatformException.error("未找到id=" + user.getId() + "的用户");
        }
        user.setPassword(existUser.getPassword());
        user.setRoles(existUser.getRoles());
        return userRepo.save(user);
    }

    public int delete(long id) {
        return userRepo.deleteById(id);
    }

   /* public List<UserDto> getAllUser() {
        String sql ="SELECT id, name,username FROM t_glam_user";
        return nMysqlNativeSqlRepository.findWithArgsT(sql,null,UserDto.class);
    }*/

    public Page<User> findPage(int pageNumber, int pageSize) {
        Sort sort = Sort.by(Sort.Direction.ASC, "id");
        Pageable pageable = PageRequest.of(pageNumber - 1, pageSize, sort);
        return userRepo.findAll(pageable);
    }

    public Page<User> findPage(Specification s, int page, int size) {
        Sort.Direction direction = Sort.Direction.DESC;
        String sort = "id";
        Pageable pageable = PageRequest.of(page - 1, size, direction, sort);
        return userRepo.findAll(s, pageable);
    }

    public User findById(long id) {
        return userRepo.findById(id);
    }

    public User findByIdAll(long id) {
        return userRepo.findByIdAll(id);
    }

    public List<User> findByRoleId(long roleId) {
        return userRepo.findByRoleId(roleId);
    }

    public List<User> findByReportId(String reportId) {
        return userRepo.findByReportId(reportId);
    }

/*    public List<MysqlReport> findByUserId(Long userId) {
        return mysqlReportRepository.findByUserId(userId);
    }*/

    public User save(User user) {
        return userRepo.save(user);
    }

    public void updatePassword(long id, String pwd) {
        userRepo.updatePassword(id, pwd);
    }

    /**
     * 用本地密码进行校验，包括系统用户和外包人员
     */
    public PlatformUserDto loginLocal(String username, String password) {
        User user = userRepo.findByUsername(username);
        if (user == null) {
            throw PlatformException.error("此系统无：" + username + ",请联系系统管理员，创建用户与权限");
        }
        // 判断用户状态是否异常
        if (Integer.valueOf(0).equals(user.getEnabled())) {
            throw PlatformException.errorWithOutMail("用户名或者密码错误!");
        }
        if (StringUtils.isBlank(user.getPassword())) {
            throw PlatformException.errorWithOutMail("登录失败，请联系管理员重置密码");
        } else if (!user.getPassword().equals(password)) {
            throw PlatformException.errorWithOutMail("用户名或者密码错误!");
        }

        // 获取用户角色信息
        Set<Url> urls = new HashSet<>();
        Set<String> userRoleNames = user.getRoles().stream().map(Role::getName).collect(Collectors.toSet());

        if (username.equals("admin") || userRoleNames.contains(ROLE_OPEARATOR)) {
            urls.addAll(urlRepo.findAll());
        } else {
            user.getRoles().forEach(role -> urls.addAll(role.getUrls()));
        }
        user.setUrls(urls);
        return PlatformUserConverter.do2Dto(user);
    }


    public PlatformUserDto getUsrUrls(String username) {

        User user = userRepo.findByUsername(username);
        if (user == null) {
            try {

                user = new User();
                user.setUsername(username);
                user.setEmail(Strings.EMPTY);
                user.setUserDepartment(Strings.EMPTY);
                user.setUrls(new HashSet<>());
                user.setRoles(new HashSet<>());
                user.setUserType(UserTypeEnum.OA.getCode());
                user.setPassword(defaultPassword);
                user.setName(username);
                AppEhrResponse<LdapEhrEmpDto> res = iFeignLdapService.getLdapEhrEmp(username, null, false);
                if (res != null) {
                    if (res.getStatus() == 0) {
                        LdapEhrEmpDto emp = res.getData();
                        if (emp != null) {
                            user.setEmail(emp.getEmail());
                            user.setName(emp.getName());
                            user.setUserid(String.valueOf(emp.getOaUserId()));
                            user.setUserDepartment(emp.getTitle());
                        } else {
                            throw new Exception("未找到用户信息：" + username);
                        }
                    }
                }
                Set<Role> itRole = new HashSet<>();
                Role role = roleRepo.queryByIdLock(35);
                if (role != null && "IT_GRP".equals(role.getName())) {
                    //新用户初始化IT资产管理权限
                    itRole.add(role);
                }
                user.setRoles(itRole);
                userRepo.save(user);
                user = userRepo.findByUsername(username);
//                UserDto userDto = new UserDto(user);
//                return userDto;
            } catch (Exception e) {
                logger.error("处理人员信息异常！", e);
            }
        } else {
            try {
                AppEhrResponse<LdapEhrEmpDto> res = iFeignLdapService.getLdapEhrEmp(username, null, false);
                if (res != null) {
                    if (res.getStatus() == 0) {
                        LdapEhrEmpDto emp = res.getData();
                        if (emp != null) {
                            if (!StringUtils.isEmpty(emp.getTitle())) {
                                user.setUserDepartment(emp.getTitle());
                            }
                            if (Objects.nonNull(emp.getOaUserId())) {
                                user.setUserid(String.valueOf(emp.getOaUserId()));
                            }
                            userRepo.save(user);
                        }
                    }
                }

            } catch (Exception e) {
                logger.error("处理人员信息异常！", e);
            }

        }
        Set<Url> urls = new HashSet<>();
        Set<String> userRoleNames = user.getRoles() == null ? new HashSet<>() : user.getRoles().stream().map(Role::getName).collect(Collectors.toSet());

        if (username.equals("admin") || userRoleNames.contains(ROLE_OPEARATOR)) {
            urls.addAll(urlRepo.findAll());
        } else {
            user.getRoles().forEach(role -> urls.addAll(role.getUrls()));
        }
        user.setUrls(urls);
        PlatformUserDto PlatformUserDto = PlatformUserConverter.do2Dto(user);
        return PlatformUserDto;


    }


    public PlatformUserDto login(String username) {
        User user = userRepo.findByUsername(username);
        if (user == null) {
            saveUserByUserName(username);
            user = userRepo.findByUsername(username);
            //需要做其他处理，不能直接返回，否则无法获取权限
//            UserDto userDto = new UserDto(user);
//            return userDto;
        } else {
            try {
                AppEhrResponse<LdapEhrEmpDto> res = iFeignLdapService.getLdapEhrEmp(username, null, false);
                if (res != null) {
                    if (res.getStatus() == 0) {
                        LdapEhrEmpDto emp = res.getData();
                        if (emp != null) {
                            if (!StringUtils.isEmpty(emp.getTitle())) {
                                user.setUserDepartment(emp.getTitle());
                            }
                            if (Objects.nonNull(emp.getOaUserId())) {
                                user.setUserid(String.valueOf(emp.getOaUserId()));
                            }
                            userRepo.save(user);
                        }
                    }
                }
            } catch (Exception e) {
                logger.error("处理人员信息异常！", e);
            }
        }
        // 判断用户状态是否异常
        if (Integer.valueOf(0).equals(user.getEnabled())) {
            throw PlatformException.error("用户状态不可用!");
        }
     /*   if (!user.getPassword().equals(password)) {
            throw GlamException.error("用户名或者密码错误!");
        }*/

        // 获取用户角色信息
        Set<Url> urls = new HashSet<>();
        Set<String> userRoleNames = user.getRoles().stream().map(Role::getName).collect(Collectors.toSet());

        if (username.equals("admin") || userRoleNames.contains(ROLE_OPEARATOR)) {
            urls.addAll(urlRepo.findAll());
        } else {
            user.getRoles().forEach(role -> urls.addAll(role.getUrls()));
        }
        user.setUrls(urls);
        return PlatformUserConverter.do2Dto(user);
    }

    /**
     * 更新没有用户姓名的责任人
     */
    public String updateUnLoginUser() {
        //网络设备，服务器，虚拟机，云平台等用户id关联用户表查询不到用户的
        List<String> userList = userRepo.getUnLoginUser();
        if (CollectionUtils.isEmpty(userList)) {
            logger.info("查不到未匹配人员");
            return null;
        } else {
            logger.info("需要匹配的人员:" + userList);
            List<String> errorInfo = new ArrayList();
            for (String userId : userList) {
                try {
                    addUser(userId);
                } catch (NumberFormatException e) {
                    errorInfo.add("用户id异常" + "---用户id" + userId);
                    continue;
                } catch (Exception e) {
                    errorInfo.add(e.getMessage() + "---用户id" + userId);
                    e.printStackTrace();
                }
            }
            if (!CollectionUtils.isEmpty(errorInfo)) {
                return JSONArray.toJSONString(errorInfo);
            } else {
                return null;
            }
        }
    }

    /**
     * 增加新用户
     *
     * @param userId
     */
    public void addUser(String userId) {
        Integer userIdInteger = Integer.valueOf(userId);
        LdapResponse<List<LdapEhrEmpDto>> resp = iFeignLdapService.getUserList(LdapEhrEmpSearchDto.builder().oaUserId(userIdInteger).build());
        if (Objects.nonNull(resp) && CollectionUtil.isNotEmpty(resp.getData())) {
            this.saveUserByUserName(resp.getData().get(0).getBadge());
        } else {
            logger.error("未找到用户信息{}", userId);
        }
    }


    public PlatformUserDto saveUserByUserName(String username) {
        User user = new User();
        user.setName(username);
        user.setUsername(username);
        user.setEmail(Strings.EMPTY);
        user.setUserDepartment(Strings.EMPTY);
        user.setUrls(new HashSet<>());
        AppEhrResponse<LdapEhrEmpDto> res = iFeignLdapService.getLdapEhrEmp(username, null, false);
        if (res != null) {
            if (res.getStatus() == 0) {
                LdapEhrEmpDto emp = res.getData();
                if (emp != null) {
                    user.setName(emp.getName());
                    user.setEmail(emp.getEmail());
                    user.setUserDepartment(emp.getTitle());
                    user.setUserid(Objects.nonNull(emp.getOaUserId()) ? String.valueOf(emp.getOaUserId()) : null);
                }
            }
        }

        Set<Role> itRole = new HashSet<>();
        Role role = roleRepo.queryByIdLock(35);
        if (role != null && "COMMON_URL".equals(role.getName())) {
            //新用户初始化IT资产管理权限
            itRole.add(role);
        }
        user.setRoles(itRole);
        user.setUserType(UserTypeEnum.OA.getCode());
        user.setPassword(defaultPassword);

        userRepo.save(user);
        logger.info("用户新增成功" + user);
        return PlatformUserConverter.do2Dto(user);
    }

    @Transactional
    public User info(String username) {
        User user = userRepo.findByUsername(username);
        if (user == null) {
            return null;  // user 为空，直接返回NULL。
            //throw GlamException.error("用户名或者密码错误!!");
        }
        user.getRoles().forEach(role -> role.toString());

        // 获取用户角色信息
        Set<Url> urls = new HashSet<>();
        user.getRoles().forEach(role -> urls.addAll(role.getUrls()));
        user.setUrls(urls);
        return user;
    }

    public PlatformUserDto findByUsername(String username) {
        return findByUserAccount(username);
    }

    public User findByUsernameNotSave(String username) {
        return userRepo.findByUsername(username);
    }

    public User findByUserId(String userId) {
        return userRepo.findByUserid(userId);
    }

    public Set<String> queryUrlsByUserId(long id) {
        return userRepo.queryUrlsByUserId(id);
    }

    /**
     * 获取用户常用菜单
     *
     * @param userName
     * @return
     */
    public UserMenuInfo findByUserName(String userName) {
        return mysqlUserMenuInfoRepository.findByUserName(userName);
    }

    public PlatformUserDto findByUserAccount(String account) {
        return Optional.ofNullable(userRepo.findByUsername(account))
                .map(PlatformUserConverter::do2Dto)
                .orElse(null);
    }

    /**
     * 保存用户常用菜单
     *
     * @param userMenuInfo
     * @return
     */
    public UserMenuInfo save(UserMenuInfo userMenuInfo) {
        return mysqlUserMenuInfoRepository.save(userMenuInfo);
    }

    @SneakyThrows
    public List<User> convertEhrEmpList(AppEhrResponse<List<LdapEhrEmp>> response) {
        List<LdapEhrEmp> userlist = response.getData();
        List<User> itUserList = new ArrayList<>();
        for (LdapEhrEmp dto : userlist) {
            if (dto.getBadge() != null) {
                User u = new User();
                u.setName(dto.getName());
                u.setUsername(dto.getBadge());
                u.setUserDepartment(dto.getTitle());
                u.setDepartmentId(dto.getDepid().toString());
                u.setEmail(dto.getEmail());
                itUserList.add(u);
            }
        }
        return itUserList;
    }

    @SneakyThrows
    public List<User> convertEhrEmpListFlowableResponse(FlowableResponse response) {
        List<Map<String, String>> userlist = (List) response.getData();
        List<User> itUserList = new ArrayList<>();
        for (Map dto : userlist) {
            if (dto.get("badge") != null) {
                User u = new User();
                u.setUsername(dto.get("badge").toString());
                u.setName(dto.get("name").toString());
                u.setUserDepartment(dto.get("title").toString());
                u.setDepartmentId(dto.get("depid").toString());
                u.setEmail(dto.get("email").toString());
                itUserList.add(u);
            }
        }
        return itUserList;
    }

    /*
     * 根据网关SSOToken获取用户account
     * 即网关SSO token解析账号
     * */
    public String getAccountByGatewaySSOToken(String gatewaySSOToken) {
        try {
            //校验据网关SSOToken
            if (StrUtil.isEmpty(gatewaySSOToken)) {
                return "";
            }

            Map<String, Object> param = new HashMap<>();

            logger.debug("根据网关SSOToken获取用户权限,gatewaySSOToken=" + gatewaySSOToken);
            String usrJson = iFeignLdapService.checkToken(LdapUserDto.builder()
                    .token(gatewaySSOToken)
                    .systemId("amprod")
                    .build());
            logger.debug("调用网关Token校验接口返回数据,gatewayResponse=" + usrJson);

            JSONObject jsonObject = JSON.parseObject(usrJson);
            String codeNumber = jsonObject.getString(PlatformConstant.RETURN_CODE_KEY);

            if (codeNumber.equals(PlatformConstant.SUCCESS)) {
                JSONObject objectData = jsonObject.getJSONObject(PlatformConstant.RETURN_DATA_KEY);
                String userName = objectData.getString(PlatformConstant.RETURN_USERNAME_KEY);
                return userName;
            } else {
                logger.debug("尝试SSO token验证失败，未能解析除正确的账户,{}", gatewaySSOToken);
                return "";
            }

        } catch (Exception e) {
            return "";
        }
    }

    /**
     * 根据requestId和用户account获取跳转oa流程链接
     *
     * @param gatewaySSOToken
     * @param requestId
     * @param userName
     * @return
     */
    public OaLinkDto getOaLinkWithSSOToken(String gatewaySSOToken, String requestId, String userName) {
        try {
            if (StrUtil.isBlank(gatewaySSOToken) || StrUtil.isBlank(requestId) || StrUtil.isBlank(userName)) {
                throw PlatformException.error("获取ssoToken发生异常,gatewaySSOToken 或 requestId 或 userName 为空 ");
            }
            OaLinkDto result = new OaLinkDto();
            LdapUserDto ldapUserDto = new LdapUserDto();
            ldapUserDto.setToken(gatewaySSOToken);
            ldapUserDto.setSystemId(PlatformConstant.SYS_ID_GATEWAY);
            ldapUserDto.setUserName(userName);

            logger.debug("根据网关SSOToken获取用户权限,gatewaySSOToken=" + gatewaySSOToken);
            LdapResponse<String> response = iFeignLdapService.checkTokenAndReturnOaToken(ldapUserDto);
            logger.debug("调用网关Token校验接口返回数据,gatewayResponse=" + response);
            if (DictConstant.GATEWAY_CODE.equals(response.getStatus())) {
                String mainUrl = systemConfigService.findConfigValueByCode(DictConstant.OA_MAIN_URL);
                String flowUrl = systemConfigService.findConfigValueByCode(DictConstant.OA_FLOW_VIEW_URL);
                result.setOaMainUrl(mainUrl + StrUtil.toString(response.getData()));
                result.setOaFlowViewUrl(flowUrl + requestId);
                return result;
            } else {
                logger.debug("尝试SSO token验证失败，未能解析出正确的账户,{}", gatewaySSOToken);
                throw PlatformException.error("尝试SSO token验证失败，未能解析出正确的账户,{}" + gatewaySSOToken);
            }
        } catch (Exception e) {
            logger.error("获取ssoToken发生异常,", e);
            throw PlatformException.error("打开OA流程页面失败，未能解析出正确的账户");
        }
    }

    public List<LdapEhrEmpDto> findUserListByUserLeaderAccountList(List<String> userList) {
        AppEhrResponse<List<LdapEhrEmpDto>> res = iFeignLdapService.findUserListByUserLeaderAccountList(userList);
        if (res != null && res.getStatus() == 0 && CollectionUtil.isNotEmpty(res.getData())) {
            return res.getData();
        }
        return Collections.EMPTY_LIST;
    }

    public List<TAmEhrDeptinfoEntity> convertEhrDeptList(AppEhrResponse<List<TAmEhrDeptinfoEntity>> response) {
        if (response != null) {
            if (response.getStatus() == 0) {
                List<TAmEhrDeptinfoEntity> deptList = response.getData();
                List<TAmEhrDeptinfoEntity> deptinfoEntityList = new ArrayList<>();
                for (TAmEhrDeptinfoEntity dto : deptList) {
                    TAmEhrDeptinfoEntity u = new TAmEhrDeptinfoEntity();
                    u.setDepid(dto.getDepid());
                    u.setAdminid(dto.getAdminid());
                    u.setAtitle(dto.getAtitle());
                    u.setDepgrade(dto.getDepgrade());
                    u.setDtitle(dto.getDtitle());
                    u.setComptitle(dto.getComptitle());
                    u.setLeader(dto.getLeader());
                    u.setLname(dto.getLname());
                    deptinfoEntityList.add(u);
                }
                return deptinfoEntityList;
            }
        }
        return null;

    }

    public List<LdapEhrEmpDto> getEmpsByAccounts(List<String> userList) {
        AppEhrResponse<List<LdapEhrEmpDto>> res = iFeignLdapService.getEmpsByAccounts(userList);
        if (res != null && res.getStatus() == 0 && CollectionUtil.isNotEmpty(res.getData())) {
            return res.getData();
        }
        return Collections.EMPTY_LIST;
    }

    public boolean userRoleContain(String roleName, String account) {
        PlatformUserDto currentUser = userCache.get(account);
        if (CollectionUtil.isNotEmpty(currentUser.getRoles()) && currentUser.getRoles().stream().anyMatch(role -> role.equals(roleName))) {
            return true;
        }
        return false;
    }

    /**
     * 获取领导下属
     *
     * @param leader
     * @return
     */
    public List<String> findAllByLeaderAccount(String leader) {
        List<LdapEhrEmpDto> levelList = this.findUserListByUserLeaderAccountList(Collections.singletonList(leader));
        List<LdapEhrEmpDto> systemAdminAccountList = new ArrayList<>(levelList);
        int i = 0;
        //BFS遍历
        while (CollectionUtil.isNotEmpty(levelList) && i < 10) {
            i++;
            List<String> userNames = levelList.stream().map(LdapEhrEmpDto::getBadge).collect(Collectors.toList());
            levelList = this.findUserListByUserLeaderAccountList(userNames);
            systemAdminAccountList.addAll(levelList);
        }
        return CollectionUtil.isNotEmpty(systemAdminAccountList) ? systemAdminAccountList.stream().map(LdapEhrEmpDto::getBadge).collect(Collectors.toList()) : Collections.EMPTY_LIST;
    }

    /**
     * 获取直属领导和一级部门领导
     */
    public UserLeadersDto getDirectLeaderAndPrimaryDepartmentLeader(PlatformUserDto staff) throws PlatformException {
        UserLeadersDto res = new UserLeadersDto();
        //本体
        AppEhrResponse<LdapEhrEmpDto> staffRes = iFeignLdapService.getLdapEhrEmp(staff.getUsername(), null, false);
        LdapEhrEmpDto staffEntity;
        if (Objects.isNull(staffRes) || staffRes.getStatus() != 0) {
            throw PlatformException.error(String.format("未找到员工%s信息", staff.getName()));
        } else {
            staffEntity = staffRes.getData();
            if (Strings.isNotBlank(staffEntity.getReportto()) && !staffEntity.getReportto().equals(staffEntity.getBadge())) {
                //直属领导
                res.getDirectLeaders().add(staffEntity.getReportto());
            }
        }
        //部门
        AppEhrResponse<LdapEhrEmpDto> ehrResponse = iFeignLdapService.gettAmEhrEmpDept(staffEntity.getBadge());
        if (Objects.isNull(ehrResponse) || ehrResponse.getStatus() != 0) {
            throw PlatformException.error("未找到部门信息");
        }
        //循环找最上级部门
        LdapEhrDeptDto department = ehrResponse.getData().getDeptinfo();
        while (Objects.nonNull(department.getParentDeptInfo())) {
            //如果当前为一级部门，将部门领导放在部门领导list中
            if ("一级部门".equals(department.getDepgrade())) {
                res.getLevelOneDepLeaders().add(department.getLeader());
            } else {
                //如果当前非一级部门，将部门领导放在直属领导list中
                res.getDirectLeaders().add(department.getLeader());
            }
            department = department.getParentDeptInfo();
        }
        res.getLevelOneDepLeaders().add(department.getLeader());
        res.getAllLeaders().addAll(res.getDirectLeaders());
        res.getAllLeaders().addAll(res.getLevelOneDepLeaders());

        //去重
        return res.distinct();
    }

    @Cacheable(cacheNames = "getUserFromEhr#6000")
    public LdapEhrEmpDto getUserFromEhr(String account) {
        //获取人员信息
        AppEhrResponse<List<LdapEhrEmpDto>> res = iFeignLdapService.getEmpsByAccounts(ImmutableList.of(account));
        return Objects.nonNull(res) && res.getStatus() == 0 && CollectionUtil.isNotEmpty(res.getData()) ? res.getData().get(0) : new LdapEhrEmpDto();
    }

    public List<LdapEhrEmpDto> getUsersFromEhr(List<String> accounts) {
        //获取人员信息
        AppEhrResponse<List<LdapEhrEmpDto>> res = iFeignLdapService.getEmpsByAccounts(accounts);
        return Objects.nonNull(res) && res.getStatus() == 0 && CollectionUtil.isNotEmpty(res.getData()) ? res.getData() : Collections.EMPTY_LIST;
    }

    public List<LdapEhrEmpDto> getUserByDepts(List<String> depts) {
        AppEhrResponse<List<LdapEhrEmpDto>> res = iFeignLdapService.getEmpsByDepts(depts);
        return Objects.nonNull(res) && res.getStatus() == 0 && CollectionUtil.isNotEmpty(res.getData()) ? res.getData() : Collections.EMPTY_LIST;
    }

    /**
     * 检查是否是系统用户
     */
    public boolean isSysUser(@NotNull String name) {
        boolean flag = false;
        User user = userRepo.findByUsername(name);
        if (Objects.nonNull(user) && StringUtils.isNotBlank(user.getUserType())) {
            UserTypeEnum userType = UserTypeEnum.valuesOf(user.getUserType());
            flag = userType.isSysUser();
        }
        return flag;
    }


    /**
     * 检查是否需要本都登录校验，同com.glsc.ngateway.ldap.service.ILdapService#needLongLocal(String name)
     */
    public boolean needLoginLocal(@NotNull String name) {
        boolean flag = false;
        User user = userRepo.findByUsername(name);
        if (Objects.nonNull(user) && StringUtils.isNotBlank(user.getUserType())) {
            UserTypeEnum userType = UserTypeEnum.valuesOf(user.getUserType());
            flag = userType.isSysUser() || userType.isLaborDispatch();
        }
        return flag;
    }

    public List<User> findAllByAccountList(List<String> accountList) {
        return CollectionUtils.isEmpty(accountList) ? Collections.EMPTY_LIST : userRepo.findAllByUsernameIn(accountList);
    }

    public List<String> getUserEmailListByAccountList(List<String> asList) {
        List<LdapEhrEmpDto> u = this.getUsersFromEhr(asList);
        return u.stream().map(LdapEhrEmpDto::getEmail).collect(Collectors.toList());
    }

    public JSONArray convertToTreeJson(List<LdapEhrDeptDto> deptinfoEntityList, @Nullable String department, @Nullable String groupBy) {
        Set<String> companySet = new HashSet<>();
        //如果查询了部门
        deptinfoEntityList = Strings.isBlank(department) ? deptinfoEntityList : deptinfoEntityList.stream()
                .filter(item -> StrUtil.equals(item.getDtitle(), department) || StrUtil.equals(item.getAtitle(), department))
                .collect(Collectors.toList());
        for (LdapEhrDeptDto deptinfoEntity : deptinfoEntityList) {
            if (StrUtil.isNotEmpty(deptinfoEntity.getComptitle())) {
                companySet.add(deptinfoEntity.getComptitle());
            }
        }

        SystemConfig subCompConfig = systemConfigService.findByCode(Constant.CONFIG_KEY_SUB_COMPANY_LIST);
        Set<String> subCompany = Objects.nonNull(subCompConfig) ? Arrays.stream(subCompConfig.getConfigValue().split(",")).collect(Collectors.toSet()) : Collections.EMPTY_SET;
        if ("subCompany".equals(groupBy)) {
            companySet = companySet.stream().filter(company -> !company.endsWith("分公司") && !company.endsWith("营业部") && !subCompany.contains(company)).collect(Collectors.toSet());
        }
        List<TreeNode> treeNodes = new ArrayList<>();
        for (String company : companySet) {
            TreeNode companyNode = new TreeNode(company, company);
            companyNode.setChildren(buildTree(deptinfoEntityList, company));
            treeNodes.add(companyNode);
        }
        JSONArray jsonArray = new JSONArray();
        for (TreeNode treeNode : treeNodes) {
            jsonArray.add(buildJson(treeNode));
        }
        if ("subCompany".equals(groupBy)) {
            //“分支机构”选项，默认包含所有“**分公司”和所有“**营业部”
            jsonArray.add(buildJson(new TreeNode(Constant.BRANCH_ORGANIZATION, Constant.BRANCH_ORGANIZATION)));
            //“子公司”选项，默认包含 华英、通宝、创新、资管子；
            jsonArray.add(buildJson(new TreeNode(Constant.SUB_COMPANY, Constant.SUB_COMPANY)));
        }
        return jsonArray;
    }

    private static List<TreeNode> buildTree(List<LdapEhrDeptDto> deptinfoEntityList, String company) {
        List<TreeNode> treeNodes = new ArrayList<>();
        for (LdapEhrDeptDto deptinfoEntity : deptinfoEntityList) {
            if (StrUtil.isNotEmpty(deptinfoEntity.getComptitle()) && deptinfoEntity.getComptitle().equals(company) && "一级部门".equals(deptinfoEntity.getDepgrade())) {
                TreeNode treeNode = new TreeNode(String.valueOf(deptinfoEntity.getDepid()), deptinfoEntity.getDtitle());
                treeNode.setChildren(buildSubTree(deptinfoEntityList, deptinfoEntity.getDepid()));
                treeNodes.add(treeNode);
            }
        }
        return treeNodes;
    }

    private static List<TreeNode> buildSubTree(List<LdapEhrDeptDto> deptinfoEntityList, int adminId) {
        List<TreeNode> treeNodes = new ArrayList<>();
        for (LdapEhrDeptDto deptinfoEntity : deptinfoEntityList) {
            if (deptinfoEntity.getAdminid() != null && deptinfoEntity.getAdminid() == adminId) {
                TreeNode treeNode = new TreeNode(String.valueOf(deptinfoEntity.getDepid()), deptinfoEntity.getDtitle());
                treeNode.setChildren(buildSubTree(deptinfoEntityList, deptinfoEntity.getDepid()));
                treeNodes.add(treeNode);
            }
        }
        return treeNodes;
    }

    private static JSONObject buildJson(TreeNode treeNode) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("title", treeNode.getTitle());
        jsonObject.put("value", String.valueOf(treeNode.getValue()));
        if (!treeNode.getChildren().isEmpty()) {
            JSONArray jsonArray = new JSONArray();
            for (TreeNode child : treeNode.getChildren()) {
                jsonArray.add(buildJson(child));
            }
            jsonObject.put("children", jsonArray);
        }
        return jsonObject;
    }

    private static class TreeNode {
        private String value;
        private String title;
        private List<TreeNode> children;

//        public TreeNode(int value, String title) {
//            this.value = value;
//            this.title = title;
//            this.children = new ArrayList<>();
//        }

        public TreeNode(String value, String title) {
            this.value = value;
            this.title = title;
            this.children = new ArrayList<>();
        }

        public String getValue() {
            return value;
        }

        public String getTitle() {
            return title;
        }

        public List<TreeNode> getChildren() {
            return children;
        }

        public void setChildren(List<TreeNode> children) {
            this.children = children;
        }
    }

    public List<User> findAllUserAccountByRoleNameIn(List<String> roleNameList) {
        List<User> userList = new ArrayList<>(0);
        if (!CollectionUtils.isEmpty(roleNameList)) {
            List<Role> roles = roleRepo.findAllByNameIn(roleNameList);
            if (!CollectionUtils.isEmpty(roles)) {
                List<Long> roleIds = roles.stream().map(Role::getId).collect(Collectors.toList());
                userList = findAllByRoleIdIn(roleIds);
            }
        }
        return userList;
    }

    public List<User> findAllByRoleIdIn(List<Long> roleIds) {
        return CollectionUtils.isEmpty(roleIds) ? new ArrayList<>(0) : userRepo.findAllByRoleIdIn(roleIds);
    }

    public List<User> findAllByDepartmentIn(List<String> depList) {
        return CollectionUtils.isEmpty(depList) ? new ArrayList<>(0) : userRepo.findAllByUserDepartmentIn(depList);
    }

    public List<String> findAccountsByType(@NotNull FlowConfigValueTypeEnum type, @Nullable List<String> param) {
        if (CollectionUtils.isEmpty(param)) {
            return param;
        }
        switch (type) {
            case ROLE:
                //角色类型
                return findAllUserAccountByRoleNameIn(param).stream().map(User::getUsername).collect(Collectors.toList());
            case ACCOUNT:
                //人员类型，直接返回
                return param;
            case DEPARTMENT:
                //部门类型
                return findAllByDepartmentIn(param).stream().map(User::getUsername).collect(Collectors.toList());
            default:
                return new ArrayList<>(0);
        }
    }

    /**
     * 通过企业微信Token获取用户名
     *
     * @return
     */
    @Nullable
    public String getUsernameByWorkWechatLoginToken(@NotBlank String token) {
        if (Strings.isBlank(token) || "null".equals(token)) {
            logger.error("企微Token查询失败：token为空");
            return null;
        }
        LdapResponse<LdapWorkWechatTokenCheckResultDto> ldapResponse = iFeignLdapService.checkWorkWechatToken(LdapWorkWechatTokenCheckParamDto.builder().token(token).build());
        logger.info("校验Token：{}，Response： {}", token, ldapResponse);
        return ldapResponse.isSuccess() ? ldapResponse.getData().getOa_account() : null;
    }

    @SneakyThrows
    @Cacheable(cacheNames = "getUserNameByLdap#6000")
    public String getUserNameByLdap(String token) {
        String tmp = feignLdapService.checkToken(LdapUserDto.builder()
                .token(token)
                .systemId("glgateway")
                .build());
        logger.info("完成Token查询,完成时间为：" + System.currentTimeMillis());
        return getUserName(tmp);
    }

    /**
     * @param usrJson
     * @return
     * @Description 根据JSON 解析UserName
     */
    public String getUserName(String usrJson) {

        JSONObject jsonObject = JSON.parseObject(usrJson);
        String codeNumber = jsonObject.getString(PlatformConstant.RETURN_CODE_KEY);

        if (codeNumber.equals(PlatformConstant.SUCCESS)) {
            JSONObject objectData = jsonObject.getJSONObject(PlatformConstant.RETURN_DATA_KEY);
            String userName = objectData.getString(PlatformConstant.RETURN_USERNAME_KEY);
            return userName;
        } else {
            return PlatformConstant.TOKEN_OVERDUE;
        }
    }
}
